extends Node


func changeScrennOrientation2Landscape():
	DisplayServer.screen_set_orientation(DisplayServer.SCREEN_LANDSCAPE)


func changeScrennOrientation2Portrait():
	DisplayServer.screen_set_orientation(DisplayServer.SCREEN_PORTRAIT)


func changeScene(sceneName):
	get_tree().current_scene.queue_free()
	var sceneInstance = ResourcePreload.resources[sceneName].instantiate() 
	get_tree().root.add_child(sceneInstance) 
	get_tree().current_scene = sceneInstance
	return sceneInstance


func createResourceInstance(resourceName):
	return ResourcePreload.resources[resourceName].instantiate() 	


func getResource(resourceName):
	return ResourcePreload.resources[resourceName]
	
	
func isOSWindows():
	var osName = OS.get_name()
	return osName == "Windows"
	
	
func angleDegree2Vector(angleDegree):
	var andRadian = deg_to_rad(angleDegree)
	var result = Vector2(cos(andRadian), sin(andRadian))
	return result.normalized()
	

func vector2AngleDegree(vec:Vector2):
	var angRadian = vec.angle()
	return rad_to_deg(angRadian)
	
	
func angleDegree2Positive(angleDegree):
	var result = angleDegree
	if result < 0:
		result += 360.0
	return result


func getCamPosition(cam:Camera2D):
	var _viewportSize = get_viewport().get_visible_rect().size
	return Vector2(cam.offset.x - _viewportSize.x / 2.0, cam.offset.y - _viewportSize.y / 2.0)
	

func setCamPosition(cam:Camera2D, pos):
	var _viewportSize = get_viewport().get_visible_rect().size
	cam.offset = Vector2(pos.x + _viewportSize.x / 2.0, pos.y + _viewportSize.y / 2.0)
	
	
func debug(msg):
	var timeDict = Time.get_datetime_dict_from_system()
	var timeStr = "%d-%02d-%02d %02d:%02d:%02d" % [timeDict["year"], timeDict["month"], timeDict["day"], timeDict["hour"], timeDict["minute"], timeDict["second"]]
	print(timeStr, " ", msg)
	
	
func getChildNodeByName(parentNode:Node2D, childNodeName):
	for index in range(parentNode.get_child_count()):
		var childNode = parentNode.get_child(index) 
		if childNodeName in childNode.name:
			return childNode
	return null
	

func clearChildNode(parentNode:Node):
	for index in range(parentNode.get_child_count()):
		parentNode.get_child(index).queue_free()
	

func createAtlasTexture(imgResource, pos, size):
	var atlasTexture = AtlasTexture.new()
	atlasTexture.atlas = imgResource
	atlasTexture.region = Rect2(pos, size)
	return atlasTexture
	
	
func cell2Pos(cell):
	var posX = cell.x * Consts.BATTLE_CELL_SIZE + Consts.BATTLE_CELL_SIZE / 2.0
	var posY = cell.y * Consts.BATTLE_CELL_SIZE + Consts.BATTLE_CELL_SIZE
	return Vector2(posX, posY)
	

func cell2PosLeftUp(cell):
	var posCenterDown = cell2Pos(cell)
	return Vector2(posCenterDown.x - Consts.BATTLE_CELL_SIZE / 2.0, posCenterDown.y - Consts.BATTLE_CELL_SIZE)
	

func cell2PosCenter(cell):
	var posCenterDown = cell2Pos(cell)
	return Vector2(posCenterDown.x, posCenterDown.y - Consts.BATTLE_CELL_SIZE / 2.0)


func cell2PosRight(cell):
	var posCenterDown = cell2Pos(cell)
	return Vector2(posCenterDown.x + Consts.BATTLE_CELL_SIZE / 2.0, posCenterDown.y - Consts.BATTLE_CELL_SIZE / 2.0)


func cell2PosLeft(cell):
	var posCenterDown = cell2Pos(cell)
	return Vector2(posCenterDown.x - Consts.BATTLE_CELL_SIZE / 2.0, posCenterDown.y - Consts.BATTLE_CELL_SIZE / 2.0)


func cell2PosUp(cell):
	var posCenterDown = cell2Pos(cell)
	return Vector2(posCenterDown.x, posCenterDown.y - Consts.BATTLE_CELL_SIZE)


func cell2PosDown(cell):
	return cell2Pos(cell)


func pos2Cell(pos):
	var cellX = floor(pos.x / Consts.BATTLE_CELL_SIZE) 
	var cellY = floor((pos.y - Consts.BATTLE_CELL_SIZE / 2.0) / Consts.BATTLE_CELL_SIZE)
	return Vector2(cellX, cellY)
	

# 主方法：计算可达范围和最短路径
func calcMovableCells(start: Vector2, maxSteps: int, blockedTiles: Array, tileCosts: Dictionary, border: Rect2) -> Dictionary:
	var directions = [Vector2(0, 1), Vector2(1, 0), Vector2(0, -1), Vector2(-1, 0)]  # 上下左右
	var reachableTiles = []  # 存储所有可到达点
	var shortestPaths = {}  # 存储到达每个点的最短路径
	var queue = []  # BFS 队列，存储 (当前点, 剩余步数, 当前路径)
	var maxRemainingSteps = {}

	# 初始化队列
	queue.append([start, maxSteps, []])

	while queue.size() > 0:
		var ele = queue.pop_front()
		var current = ele[0]
		var remainingSteps = ele[1]
		var path = ele[2]
		
		# 如果当前点已记录且剩余步数不足，跳过
		if current in maxRemainingSteps and remainingSteps <= maxRemainingSteps[current]:
			continue

		maxRemainingSteps[current] = remainingSteps
		if current not in reachableTiles:
			reachableTiles.append(current)
		shortestPaths[current] = path + [current]  # 记录路径

		# 扩展到相邻的格子
		for direction in directions:
			var neighbor = current + direction
	
			# 跳过无法通行的点
			if neighbor in blockedTiles:
				continue
				
			#超出边界
			if neighbor.x < border.position.x or neighbor.x >= border.size.x or neighbor.y < border.position.y or neighbor.y >= border.size.y:
				continue

			# 获取格子的移动代价，默认为 1
			var cost = tileCosts.get(neighbor, 1)
			if remainingSteps >= cost:
				queue.append([neighbor, remainingSteps - cost, path + [current]])

	return {
		"movableCells": reachableTiles,
		"shortestPaths": shortestPaths
	}
	
	
func fMoveTowards(current, target, maxDelta):
	if abs(target - current) <= maxDelta:
		return target
	return current + sign(target - current) * maxDelta
	

func createSequenceNode(_func, params = null):
	return CustomClasses.SequenceNode.new(_func, params)
	
	
func sn(_func, params = null):
	return createSequenceNode(_func, params)
	

func snEmpty():
	return createSequenceNode(emptySequenceNodeFunc)
	

func emptySequenceNodeFunc():
	return true
